package com.mobilesales.android.activities.tasks;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Spinner;
import android.widget.Button;
import android.widget.TextView;

import com.mobilesales.android.R;
import com.mobilesales.android.activities.ModelActivity;
import com.mobilesales.android.adapters.ClientSimpleArrayAdapter;
import com.mobilesales.android.adapters.EmployeeArrayAdapter;
import com.mobilesales.android.adapters.TaskStatusArrayAdapter;
import com.mobilesales.android.adapters.TaskTypeArrayAdapter;
import com.mobilesales.android.model.clients.Client;
import com.mobilesales.android.model.employees.Employee;
import com.mobilesales.android.model.tasks.CyclicTask;
import com.mobilesales.android.model.tasks.Task;
import com.mobilesales.android.model.tasks.TaskStatus;
import com.mobilesales.android.model.tasks.TaskType;
import com.mobilesales.android.util.Constants;
import com.mobilesales.android.util.DateUtil;
import com.mobilesales.android.util.MessageBox;
import com.mobilesales.android.util.Temp;

public class StoreTask extends ModelActivity<Task> {

	private int taskId;
	private boolean isCyclicTask;

	private TaskTypeArrayAdapter taskTypeAdapter;
	private TaskStatusArrayAdapter taskStatusAdapter;
	private ClientSimpleArrayAdapter clientAdapter;
	private EmployeeArrayAdapter employeeAdapter;

	private Spinner taskTypeSelect;
	private Spinner taskStatusSelect;
	private Spinner clientSelect;
	private Spinner employeeSelect;
	private EditText startTimeField;
	private EditText endTimeField;
	private EditText dateField;
	private EditText infoField;
	private SeekBar intervalSeekBar;
	private EditText priorityField;
	private LinearLayout intervalRow;
	private TextView taskIntervalLbl;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.task_store);

		taskTypeSelect = (Spinner) this.findViewById(R.id.taskTypeSpinner);
		taskStatusSelect = (Spinner) this.findViewById(R.id.taskStatusSpinner);
		clientSelect = (Spinner) this.findViewById(R.id.clientSpinner);
		employeeSelect = (Spinner) this.findViewById(R.id.employeeSpinner);
		infoField = (EditText) this.findViewById(R.id.infoTxt);
		startTimeField = (EditText) this.findViewById(R.id.startTime);
		endTimeField = (EditText) this.findViewById(R.id.endTime);
		dateField = (EditText) this.findViewById(R.id.date);
		intervalSeekBar = (SeekBar) this.findViewById(R.id.taskIntervalSeekBar);
		intervalRow = (LinearLayout) this.findViewById(R.id.taskIntervalRow);
		priorityField = (EditText) this.findViewById(R.id.priority);
		taskIntervalLbl = (TextView)this.findViewById(R.id.taskIntervalLbl);
		intervalSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
			
			public void onStopTrackingTouch(SeekBar seekBar) {}
			public void onStartTrackingTouch(SeekBar seekBar) {}
			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {
				taskIntervalLbl.setText(progress+" d");
			}
		});
		
		Bundle bundle = this.getIntent().getExtras();
		if (bundle != null && bundle.containsKey(Constants.IsCyclicTask)) {

			this.initializeSelectLists();
			isCyclicTask = bundle.getBoolean(Constants.IsCyclicTask);
			
			if (!isCyclicTask) {
				intervalRow.setVisibility(View.GONE);
				taskIntervalLbl.setVisibility(View.GONE);
			}
			else {
				intervalSeekBar.setProgress(1);
				taskIntervalLbl.setText("1 d");
			}
			
			Date now = new Date();
			if (bundle.containsKey(Constants.SelectedDate)) {
				Date date = (Date) bundle.get(Constants.SelectedDate);
				dateField.setText(DateUtil.toShortDateString(date));
			} else {
				dateField.setText(DateUtil.toShortDateString(now));
			}
			startTimeField.setText(DateUtil.toTimeString(now));
			endTimeField.setText(DateUtil.toTimeString(now));

			if (bundle.containsKey(Constants.TaskId)) {

				taskId = bundle.getInt(Constants.TaskId);
				loadItem();
			} else {
				((Button) this.findViewById(R.id.actionBtn))
						.setText(getString(R.string.Add));
			}

		} else {
			MessageBox.show(this, getString(R.string.ErrorTask));
		}
	}

	private void initializeSelectLists() {
		List<TaskStatus> statuses = this.getTaskStatusList();
		List<TaskType> types = this.getTaskTypeList();
		List<Client> clients = this.getClients();
		List<Employee> employees = this.getEmployees();
		if (statuses != null && types != null && clients != null) {
			this.taskStatusAdapter = new TaskStatusArrayAdapter(this,
					R.layout.select_list_item, statuses);
			taskStatusSelect.setAdapter(taskStatusAdapter);
			this.fixSpinner(taskStatusSelect);
			this.taskTypeAdapter = new TaskTypeArrayAdapter(this,
					R.layout.select_list_item, types);
			taskTypeSelect.setAdapter(taskTypeAdapter);
			this.fixSpinner(taskTypeSelect);
			this.clientAdapter = new ClientSimpleArrayAdapter(this,
					R.layout.select_list_item, clients, true);
			clientSelect.setAdapter(clientAdapter);
			this.fixSpinner(clientSelect);
			this.employeeAdapter = new EmployeeArrayAdapter(this,
					R.layout.select_list_item, employees);
			employeeSelect.setAdapter(employeeAdapter);
			this.fixSpinner(employeeSelect);
		} else {
			MessageBox.show(this, getString(R.string.ErrorSelectLists));
		}

	}

	private void loadItem() {
		Task task = null;
		if (isCyclicTask)
			task = getCyclicTask(taskId);
		else
			task = getTask(taskId);
		if (task != null)
			this.setModel(task);
		else
			MessageBox.show(this, getString(R.string.ErrorTask));
	}

	@Override
	protected void setModel(Task model) {
		super.setModel(model);
		if (isCyclicTask) {
			this.intervalSeekBar.setProgress(((CyclicTask) model).TaskInterval);
			taskIntervalLbl.setText(this.intervalSeekBar.getProgress());
		}

		taskTypeSelect.setSelection(taskTypeAdapter
				.getPosition(model.TaskType.Id));
		taskStatusSelect.setSelection(taskStatusAdapter
				.getPosition(model.TaskStatus.Id));

		Integer employeeId;
		if (isCyclicTask)
			employeeId = ((CyclicTask) model).EmployeeId;
		else
			employeeId = getEmployeeIdFromSchedule(model.ScheduleId);
		if (employeeId != null) {
			employeeSelect
					.setSelection(employeeAdapter.getPosition(employeeId));
		} else {
			MessageBox.show(this, getString(R.string.ErrorEmployee));
			finish();
		}

		clientSelect.setSelection(clientAdapter.getPosition(model.ClientId));
		String startTime = model.StartTime.split(" ")[1];
		String endTime = model.EndTime.split(" ")[1];
		String date = model.EndTime.split(" ")[0];

		startTimeField.setText(startTime);
		endTimeField.setText(endTime);
		dateField.setText(date);
		infoField.setText(model.Info);
		priorityField.setText(String.valueOf(model.Priority));
	}

	public void store(View v) {
		if (validate()) {
			Task task = this.getModel();
			if (task == null) {
				if (isCyclicTask)
					task = new CyclicTask();
				else
					task = new Task();
			}
			if (isCyclicTask) {
				((CyclicTask) task).TaskInterval = intervalSeekBar
						.getProgress();
			}

			Client selectedClient = (Client) clientSelect.getSelectedItem();
			task.ClientId = (selectedClient.Id != 0) ? selectedClient.Id : null;

			task.StartTime = dateField.getText() + " "
					+ startTimeField.getText();
			task.EndTime = dateField.getText() + " " + endTimeField.getText();
			task.Info = infoField.getText().toString();
			task.Priority = Integer.parseInt(priorityField.getText().toString());
			task.TaskStatus = (TaskStatus) taskStatusSelect.getSelectedItem();
			task.TaskType = (TaskType) taskTypeSelect.getSelectedItem();

			if (isCyclicTask) {
				if (save((CyclicTask) task))
					finish();
				else
					MessageBox.show(this, getString(R.string.ErrorSave));
			} else {
				if (save(task))
					finish();
				else
					MessageBox.show(this, getString(R.string.ErrorSave));
			}

		} else {
			MessageBox.show(this, getString(R.string.ErrorValidate));
		}
	}

	private boolean save(CyclicTask task) {
		// TODO; save cyclic task
		return true;
	}

	private boolean save(Task task) {
		// TODO; save task
		return true;
	}

	private Integer getEmployeeIdFromSchedule(Integer scheduleId) {
		// TODO; get it from local database
		return 1;
	}

	private List<Employee> getEmployees() {
		// TODO: get employees from local database
		return Temp.getEmployees();
	}

	private List<Client> getClients() {
		// TODO: get clients from local database
		return Arrays.asList(Temp.getClients());
	}

	private CyclicTask getCyclicTask(int taskId) {
		// TODO: get cyclic task from local database
		return Temp.getCyclicTasks()[0];
	}

	private Task getTask(int taskId) {
		// TODO: get task from local database
		return Temp.getTasks()[0];
	}

	private List<TaskType> getTaskTypeList() {
		// TODO: get task types from local database
		return Temp.getTaskTypes();
	}

	private List<TaskStatus> getTaskStatusList() {
		// TODO: get task statuses from local database
		return Temp.getTasksStatuses();
	}

	@Override
	protected boolean validate() {
		boolean valid = true;
		String date = this.dateField.getText().toString();
		if (DateUtil.parseShortDate(date)==null) {
			this.dateField.setError(getString(R.string.ErrorInvalidValue));
			valid = false;
		}

		String timeRegexp = "(20|21|22|23|[01]\\d|\\d)(([:][0-5]\\d){1,2})";
		
		String startTime = this.startTimeField.getText().toString();
		if (!startTime.matches(timeRegexp)) {
			this.startTimeField.setError(getString(R.string.ErrorInvalidValue));
			valid = false;		
		}

		String endTime = this.endTimeField.getText().toString();
		if (!endTime.matches(timeRegexp)) {
			this.endTimeField.setError(getString(R.string.ErrorInvalidValue));
			valid = false;		
		}		
		
		String priority = this.priorityField.getText().toString();
		try {
			Integer.parseInt(priority);
		}
		catch(Exception ex) {
			this.priorityField.setError(getString(R.string.ErrorInvalidValue));
			valid = false;
		}
		
		return valid;
	}

	public void refresh() {
		initializeSelectLists();
		loadItem();
	}

}
